#ifndef __ZHU_OS_KERNEL64_TASK_H__
#define __ZHU_OS_KERNEL64_TASK_H__
#include "types.h"

#define NR_TASKS 64

typedef void* (*task_fun_t)(void*);

typedef enum task_state_t 
{
    TASK_INIT,
    TASK_RUNNING,
    TASK_READY,
    TASK_BLOCKED,
    TASK_SLEEPING,
    TASK_WAITING,
    TASK_DIED,
} task_state_t;

typedef struct 
{
    int64 rflags; // 8 * 0
    int64 rip; // 8 * 1
    int64 rax; // 8 * 2
    int64 rbx; // 8 * 3
    int64 rcx; // 8 * 4
    int64 rdx; // 8 * 5
    int64 rdi; // 8 * 6
    int64 rsi; // 8 * 7
    int64 rbp; // 8 * 8
    int64 rsp; // 8 * 9
    int64 r8; // 8 * 10
    int64 r9; // 8 * 11
    int64 r10; // 8 * 12
    int64 r11; // 8 * 13
    int64 r12; // 8 * 14
    int64 r13; // 8 * 15
    int64 r14; // 8 * 16
    int64 r15; // 8 * 17
    int64 cs; // 8 * 18
    int64 ss; // 8 * 19
    int64 ds; // 8 * 20
    int64 fs; // 8 * 21
    int64 gs; // 8 * 22
    int64 es // 8 * 23
} __attribute__((packed)) task_context_t;

typedef struct task_t 
{
    int pid;
    char name[32];
    task_state_t state;
    task_fun_t function;
    task_context_t context;
    int scheduling_times;
    int exit_code;
    int64 esp0;
} __attribute__((packed)) task_t;

task_t* task_create(task_fun_t fun, char* name);

task_fun_t get_task_function(task_t* task);

task_context_t* get_task_context(task_t* task);

int inc_scheduling_times(task_t* task);

void task_init();

void sched();

task_t* sched64(void);

void task_exit(task_t* task, int exit_code);

int64 get_esp0(task_t* task);

void set_task_ready(task_t* task);

#endif